package com.github.jlmd.animatedcircleloadingview.component;

import com.github.jlmd.animatedcircleloadingview.animator.AnimationState;
import com.github.jlmd.animatedcircleloadingview.animator.MyStateChange;
import com.github.jlmd.animatedcircleloadingview.animator.MyValueAnimator;
import ohos.agp.animation.Animator;
import ohos.agp.animation.AnimatorValue;
import ohos.agp.components.Component;
import ohos.agp.render.Arc;
import ohos.agp.render.Canvas;
import ohos.agp.render.Paint;
import ohos.agp.utils.Color;
import ohos.agp.utils.RectFloat;
import ohos.app.Context;

/**
 * @author jlmd
 */
public class SideArcsView extends ComponentViewAnimation implements Component.DrawTask {
    private static final int MIN_RESIZE_ANGLE = 8;
    private static final int MAX_RESIZE_ANGLE = 45;
    private static final int INITIAL_LEFT_ARC_START_ANGLE = 100;
    private static final int INITIAL_RIGHT_ARC_START_ANGLE = 80;
    private static final int MIN_START_ANGLE = 0;
    private static final int MAX_START_ANGLE = 165;
    private int startLeftArcAngle = INITIAL_LEFT_ARC_START_ANGLE;
    private int startRightArcAngle = INITIAL_RIGHT_ARC_START_ANGLE;
    private Paint paint;
    private RectFloat oval;
    private int arcAngle;
    private boolean isReset = false;

    public SideArcsView(Context context, int parentWidth, Color mainColor, Color secondaryColor) {
        super(context, parentWidth, mainColor, secondaryColor);
        init();
        addDrawTask(this);
    }

    private void init() {
        initPaint();
        arcAngle = MAX_RESIZE_ANGLE;
        initOval();
    }

    private void initPaint() {
        paint = new Paint();
        paint.setColor(mainColor);
        paint.setStrokeWidth(strokeWidth);
        paint.setStyle(Paint.Style.STROKE_STYLE);
        paint.setAntiAlias(true);
    }

    private void initOval() {
        float padding = paint.getStrokeWidth() / 2;
        oval = new RectFloat(padding, padding, parentWidth - padding, parentWidth - padding);
    }

    @Override
    public void onDraw(Component component, Canvas canvas) {
        if (!isReset) {
            drawArcs(canvas);
        }
    }

    private void drawArcs(Canvas canvas) {
        canvas.drawArc(oval, new Arc(startLeftArcAngle, arcAngle, false), paint);
        canvas.drawArc(oval, new Arc(startRightArcAngle, -arcAngle, false), paint);
    }

    public void startRotateAnimation() {
        MyValueAnimator valueAnimatorRotate = new MyValueAnimator();
        valueAnimatorRotate.setFloat(MIN_START_ANGLE, MAX_START_ANGLE);
        valueAnimatorRotate.setCurveType(Animator.CurveType.DECELERATE);
        valueAnimatorRotate.setDuration(550);
        valueAnimatorRotate.setValueUpdateListener(new AnimatorValue.ValueUpdateListener() {
            @Override
            public void onUpdate(AnimatorValue animatorValue, float value) {
                isReset = false;
                startLeftArcAngle = INITIAL_LEFT_ARC_START_ANGLE + (int) value;
                startRightArcAngle = INITIAL_RIGHT_ARC_START_ANGLE - (int) value;
                invalidate();
            }
        });
        valueAnimatorRotate.start();
    }

    public void startResizeDownAnimation() {
        MyValueAnimator valueAnimator = new MyValueAnimator();
        valueAnimator.setFloat(MAX_RESIZE_ANGLE, MIN_RESIZE_ANGLE);
        valueAnimator.setCurveType(Animator.CurveType.DECELERATE);
        valueAnimator.setDuration(620);
        valueAnimator.setValueUpdateListener(new AnimatorValue.ValueUpdateListener() {
            @Override
            public void onUpdate(AnimatorValue animatorValue, float value) {
                arcAngle = (int) value;
                invalidate();
            }
        });
        valueAnimator.setStateChangedListener(new MyStateChange() {
            @Override
            public void onStart(Animator animator) {
                isReset = false;
            }

            @Override
            public void onEnd(Animator animator) {
                setState(AnimationState.SIDE_ARCS_RESIZED_TOP);
            }
        });
        valueAnimator.start();
    }

    public void reset() {
        arcAngle = 0;
        startLeftArcAngle = 0;
        startRightArcAngle = 0;
        initOval();
        isReset = false;
        invalidate();
    }
}
